package Action.user;


import Action.BackgroundThread.RecommendedbooksThread;
import Action.Sys.Setting;
import Bean.BookInfoEntity;
import Bean.Bookrecommend;
import Bean.LoanBookLogRecord;
import Bean.UserinfoEntity;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import org.hibernate.Session;
import tools.HibernateTools;
import tools.TimeTools;

import java.sql.Timestamp;
import java.util.*;

//只做界面显示不做任何处理
public class UserHome extends ActionSupport {
    int user_id;
    UserinfoEntity userinfoEntity;
    ArrayList<BookInfoEntity> hot_books;
    ArrayList<BookInfoEntity> vister_books;
    ArrayList<BookInfoEntity> new_books;
    ArrayList<BookInfoEntity> comment_books;
    HashSet<BookInfoEntity> Recommend_books;
    List<Object[]> TopUsers;
    List<LoanBookLogRecord> orders;// 订单日志预览
    LinkedList<String> Todo;
    int myorder_size;
    int finish_order_size;
    String data_time;//数据生成日期
    String login_time;

    Session session;


    @Override
    public String execute() throws Exception {
        RecommendedbooksThread.sys_busy=true;
        try {
            user_id = (int) ActionContext.getContext().getSession().get("userid");
        } catch (Exception e) {
            return LOGIN;
        }
        HashSet<BookInfoEntity> bookInfoEntities=new HashSet<>();//最终图片生成来源
        session = HibernateTools.getSession();

        if (userinfoEntity==null){
//            生成用户信息
            userinfoEntity=session.get(UserinfoEntity.class, user_id);
            if (userinfoEntity==null){
                return LOGIN;
            }
        }
        myorder_size=session.createQuery("from LoanBookLogRecord where userId=? ")
                .setParameter(0,user_id)
                .getResultList().size();

        finish_order_size=session.createQuery("from LoanBookLogRecord where userId=? and (state=? or state=?)")
                .setParameter(0,user_id)
                .setParameter(1, Setting.LoanBook_state_closed)
                .setParameter(2, Setting.LoanBook_state_cancel)
                .getResultList().size();


        hot_books= (ArrayList<BookInfoEntity>) session.createQuery("from BookInfoEntity order by used desc ").setMaxResults(11).getResultList();
        vister_books= (ArrayList<BookInfoEntity>) session.createQuery("from BookInfoEntity order by vister desc ").setMaxResults(11).getResultList();
        new_books= (ArrayList<BookInfoEntity>) session.createQuery("from BookInfoEntity order by id desc ").setMaxResults(8).getResultList();
        //此数据及时性最差隔一段时间再更新每个图书的评论数目
        comment_books= (ArrayList<BookInfoEntity>) session.createQuery("from BookInfoEntity order by comment_size desc ").setMaxResults(11).getResultList();

        //待办生成
        Build_Todo();

        //订单预览
        orders=session.createQuery("from LoanBookLogRecord where userId="+user_id+" order by id desc ")
                .setMaxResults(15)
                .getResultList();

        //上次登录时间

        //推荐图书
        Recommend_books=new HashSet<>();
        Bookrecommend bookrecommend = session.get(Bookrecommend.class, user_id);
        if (bookrecommend!=null) {
            //获取图书信息
            for (Integer integer : bookrecommend.formatData()) {
                Recommend_books.add(session.get(BookInfoEntity.class, integer));
            }
        }
        if (Recommend_books.size()<4){
            Recommend_books.addAll(hot_books);
        }
        bookInfoEntities.addAll(Recommend_books);
        bookInfoEntities.addAll(hot_books);
        bookInfoEntities.addAll(vister_books);
        bookInfoEntities.addAll(comment_books);
        //数据优化--暂时停止--会破坏排行榜真实性
//        optimizationData(bookInfoEntities, hot_books);
//        optimizationData(bookInfoEntities, vister_books);
//        optimizationData(bookInfoEntities, new_books);
//        optimizationData(bookInfoEntities, comment_books);





        //构建图书图片
        for (BookInfoEntity bookInfoEntity : bookInfoEntities) {
            bookInfoEntity.build_image(false);
        }
        Long time=0L;
        TopUsers=Setting.getTopLoanUser(20,time);
        data_time= TimeTools.timeStamp2Date(new Timestamp(time), "HH:MM");
        HibernateTools.commit(session);
        return SUCCESS;
    }

    //数据优化--尽可能去重
    private void optimizationData(HashSet<BookInfoEntity> data,ArrayList<BookInfoEntity> list){
        int size=6;// 图书太少先写小此数据
        if (list.size()<=size){//数据量过小
            return;
        }
        //尽可能使得所有列表数据不重复
        ArrayList<BookInfoEntity> middle=new ArrayList<>(list);
        for (BookInfoEntity bookInfoEntity : list) {
            if (data.contains(bookInfoEntity)){
                middle.remove(bookInfoEntity);
            }
            if (middle.size()<size)
                break;
        }
        list.clear();
        list.addAll(middle);
        data.addAll(middle);
    }

    public void Build_Todo() throws Exception {
        Todo=new LinkedList<>();
        List<LoanBookLogRecord> loanBookLogRecords=session.createQuery("from LoanBookLogRecord where userId="+user_id+" order by id desc ").getResultList();
        for (LoanBookLogRecord loanBookLogRecord : loanBookLogRecords) {
            BookInfoEntity bookInfoEntity=session.get(BookInfoEntity.class, loanBookLogRecord.getBookId());
            if (loanBookLogRecord.getState().equals(Setting.LoanBook_state_closed)||loanBookLogRecord.getState().equals(Setting.LoanBook_state_cancel))
                continue;
            if (loanBookLogRecord.getState().equals(Setting.LoanBook_state_reservation)){
                Todo.add("你订购的"+bookInfoEntity.getBook_name()+"还没取出,请于今天完成取书");
                continue;
            }

            if (loanBookLogRecord.getState().equals(Setting.LoanBook_state_need_TimeOut)||loanBookLogRecord.remainingDays()<0){
                Todo.add("你所借的图书"+bookInfoEntity.getBook_name()+"已经超时,请尽快归还");
                continue;
            }
            if (loanBookLogRecord.getState().equals(Setting.LoanBook_state_need_Return)){
                Todo.add("你订购的图书"+bookInfoEntity.getBook_name()+"需要在"+loanBookLogRecord.remainingDays()+"天内归还");
            }
        }

    }
    public ArrayList<BookInfoEntity> getHot_books() {
        return hot_books;
    }

    public void setHot_books(ArrayList<BookInfoEntity> hot_books) {
        this.hot_books = hot_books;
    }

    public ArrayList<BookInfoEntity> getVister_books() {
        return vister_books;
    }

    public void setVister_books(ArrayList<BookInfoEntity> vister_books) {
        this.vister_books = vister_books;
    }

    public ArrayList<BookInfoEntity> getNew_books() {
        return new_books;
    }

    public void setNew_books(ArrayList<BookInfoEntity> new_books) {
        this.new_books = new_books;
    }

    public ArrayList<BookInfoEntity> getComment_books() {
        return comment_books;
    }

    public void setComment_books(ArrayList<BookInfoEntity> comment_books) {
        this.comment_books = comment_books;
    }

    public HashSet<BookInfoEntity> getRecommend_books() {
        return Recommend_books;
    }

    public void setRecommend_books(HashSet<BookInfoEntity> recommend_books) {
        Recommend_books = recommend_books;
    }

    public int getUser_id() {
        return user_id;
    }

    public void setUser_id(int user_id) {
        this.user_id = user_id;
    }

    public int getMyorder_size() {
        return myorder_size;
    }

    public void setMyorder_size(int myorder_size) {
        this.myorder_size = myorder_size;
    }

    public int getFinish_order_size() {
        return finish_order_size;
    }

    public void setFinish_order_size(int finish_order_size) {
        this.finish_order_size = finish_order_size;
    }

    public UserinfoEntity getUserinfoEntity() {
        return userinfoEntity;
    }

    public void setUserinfoEntity(UserinfoEntity userinfoEntity) {
        this.userinfoEntity = userinfoEntity;
    }

    public List<Object[]> getTopUsers() {
        return TopUsers;
    }

    public void setTopUsers(List<Object[]> topUsers) {
        TopUsers = topUsers;
    }

    public String getData_time() {
        return data_time;
    }

    public void setData_time(String data_time) {
        this.data_time = data_time;
    }

    public LinkedList<String> getTodo() {
        return Todo;
    }

    public void setTodo(LinkedList<String> todo) {
        Todo = todo;
    }

    public List<LoanBookLogRecord> getOrders() {
        return orders;
    }

    public void setOrders(List<LoanBookLogRecord> orders) {
        this.orders = orders;
    }

    public String getLogin_time() {
        return login_time;
    }

    public void setLogin_time(String login_time) {
        this.login_time = login_time;
    }
}
